package variabilitysmelldetection.measurement.models;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.SingleVariableDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclaration;

import variabilitysmelldetection.measurement.measures.Measure;


public class MethodItem extends Item {
	private ComponentItem componentItem;
	private String returnType;
	private boolean isArrayType;
	private boolean isPrimitiveType;
	private List<String> parametersTypes;
	
	public MethodItem(ComponentItem parent, String name) {
		super(parent.getName(), name);
		this.componentItem = parent;
		parametersTypes = new ArrayList<String>();
	}
	
	public String getParentName() {
		return componentItem.getParentName();
	}
	
	public ComponentItem getParent(){
		return componentItem;
	}
	
	public String getReturnType() {
		return returnType;
	}

	public void setReturnType(String returnType) {
		this.returnType = returnType;
	}

	public boolean isArrayType() {
		return isArrayType;
	}

	public void setArrayType(boolean isTypeArray) {
		this.isArrayType = isTypeArray;
	}

	public boolean isPrimitiveType() {
		return isPrimitiveType;
	}

	public void setPrimitiveType(boolean isTypePrimitive) {
		this.isPrimitiveType = isTypePrimitive;
	}
	
	public List<String> getParametersTypes() {
		return parametersTypes;
	}

	public void setParametersTypes(List<String> parametersTypes) {
		this.parametersTypes = parametersTypes;
	}
	
	public static List<String> getParameters(MethodDeclaration method) {
		List<String> params = new ArrayList<String>();
	
		for (Object parameter : method.parameters()) {
			VariableDeclaration variableDeclaration = (VariableDeclaration) parameter;
			String type = variableDeclaration.getStructuralProperty(SingleVariableDeclaration.TYPE_PROPERTY).toString();
			for (int i = 0; i < variableDeclaration.getExtraDimensions(); i++) {
				type += "[]";
			}
			params.add(type);
	
		}
			
		return params;
	}
	
	public static String getMethodNameWithParameters(MethodDeclaration method){
		StringBuilder signature = new StringBuilder();
		signature.append(method.getName());
		signature.append("(");
	
		for (String parameter : getParameters(method)) {
			signature.append(parameter);
			signature.append(", ");
	
		}
		// removendo a ultima virgula e seu respectivo espaco
		if (signature.lastIndexOf(",") > 0) {
			signature.replace(signature.lastIndexOf(","), signature.length(), "");
		}
		signature.append(")");
	
		return signature.toString();
	}
	
	public String getFieldsAndMeasuresNames(){
		StringBuilder dados = new StringBuilder();
		dados.append("Feature");
		dados.append(";");
		dados.append("Component");
		dados.append(";");
		dados.append("Method");
		dados.append(";");
		dados.append("Refinement");
		dados.append(";");
		for (Measure m : getMeasures()) {
			dados.append(m.getAcronym());
			dados.append(";");
		}
		return dados.toString();
	}
	
	public String toCSV() {
		StringBuffer buffer = new StringBuffer();		
		buffer.append(componentItem.getParentName()); //feature
		buffer.append(";");
		buffer.append(componentItem.getName()); // class
		buffer.append(";");
		buffer.append(getName()); // method
		buffer.append(";");
		buffer.append(isRefinement() ? "Y" : "N");
		buffer.append(";");
		for (Measure m : getMeasures()) {
			buffer.append(NumberFormat.getNumberInstance().format(m.getValue()));
			buffer.append(";");
		}
		
		return buffer.toString();
	}

	public String toString(){
		return componentItem.getParentName()+"/"+
				componentItem.getName()+"/"+
				getName();
	}


}